﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Math.Geometry;

namespace Bildverarbeitung.CGFilter //CG_Door_Feature_Extraction.CGFilter
{
    class PaulheimAnnikaFilter : Bildverarbeitung.IFilter
    {

        public Bitmap GetImageWithDoor(Bitmap image)
        {
            // in Graustufen umwandeln
            Grayscale grayscale = new Grayscale(0.2125, 0.7154, 0.0721);
            Bitmap grayImage = grayscale.Apply(image);

            // Kantenerkennung
            CannyEdgeDetector edge = new CannyEdgeDetector(10, 30);
            Bitmap edgeImage = edge.Apply(grayImage);

            // Hough-Transformation
            HoughLineTransformation hough = new HoughLineTransformation();
            hough.ProcessImage(edgeImage);
            Bitmap houghLineImage = hough.ToBitmap();

            // Sättigung -20%
            SaturationCorrection saturationFilter = new SaturationCorrection(-0.2f);
            saturationFilter.ApplyInPlace(image);

            // Geraden zeichnen
            HoughLine[] lines = hough.GetLinesByRelativeIntensity(0.65);         

            UnmanagedImage unmanagedImage = UnmanagedImage.FromManagedImage(image);

            // Array of normal Lines
            Line[] nLines = new Line[lines.Length];

            for (int i = 0; i < lines.Length; i++)
            {
                // get line's radius and theta values
                int r = lines[i].Radius;
                double t = lines[i].Theta;

                // check if line is in lower part of the image
                if (r < 0)
                {
                    t += 180;
                    r = -r;
                }

                // convert degrees to radians
                t = (t / 180) * Math.PI;

                // get image centers (all coordinate are measured relative
                // to center)
                int w2 = image.Width / 2;
                int h2 = image.Height / 2;

                double x0 = 0, x1 = 0, y0 = 0, y1 = 0;

                if (lines[i].Theta != 0)
                {
                    // none-vertical line
                    x0 = -w2; // most left point
                    x1 = w2;  // most right point

                    // calculate corresponding y values
                    y0 = (-Math.Cos(t) * x0 + r) / Math.Sin(t);
                    y1 = (-Math.Cos(t) * x1 + r) / Math.Sin(t);
                }
                else
                {
                    // vertical line
                    x0 = lines[i].Radius;
                    x1 = lines[i].Radius;

                    y0 = h2;
                    y1 = -h2;
                }

                // draw line on the image
                Drawing.Line(unmanagedImage,
                    new IntPoint((int)x0 + w2, h2 - (int)y0),
                    new IntPoint((int)x1 + w2, h2 - (int)y1),
                    Color.Green);

                nLines[i] = Line.FromPoints(new IntPoint((int)x0 + w2, h2 - (int)y0), new IntPoint((int)x1 + w2, h2 - (int)y1));
            }
            

            // Eckpunkte rot hervorheben            
            foreach (Line line in nLines)
            {                
                foreach (Line secondLine in nLines)
                {
                    if (!line.Equals(secondLine))
                    {
                        AForge.Point? p = line.GetIntersectionWith(secondLine);
                        if (p.HasValue)
                        {
                            AForge.Point ed = p.GetValueOrDefault();
                            Drawing.FillRectangle(unmanagedImage, new Rectangle((int)ed.X - 5, (int)ed.Y - 5, 10, 10), Color.Red);
                        }
                    }
                }
            }

            Bitmap grayHoughImage = unmanagedImage.ToManagedImage();
            
            return grayHoughImage;       
        }

        public String GetName()
        {
            return ("PaulheimAnnika");
        }
    }
}
